/*! \file
 * \brief Enter a brief description here.
 *
 * Enter a detailed description here. (optional)
 * \author Author (Ivo Wingelaar)
 * \date Date (2011)
 * \version Version (0.0.1)
 * \copyright Copyright (GNU LGPL v3)
 */

#include "LynxLogManager_C.hpp"
#include <stdio.h>

namespace Lynx
{

/** constructor **/
/// \param    LYNX_E_LOG_LEVEL level
///         The desired log-level of the logmanager.
LogManager_C::LogManager_C(LYNX_E_LOG_LEVEL level) :
    mReceiver(0),
    mLevel(level),
    mOutputs()
{
    //
}

/** default destructor **/
LogManager_C::~LogManager_C()
{
    log("LogManager", "Closing all log-outputs", ELL_INFORMATION);

    for(uint32_t a = 0; a < mOutputs.size(); a++)
        mOutputs[a]->decrement_counter();
    mOutputs.clear();
}

/** const virtual function **/
/** get_log_level          **/
//! Returns the logging level.
/// \return LYNX_E_LOG_LEVEL
///         The logging level.
/// \param  void
LYNX_E_LOG_LEVEL LogManager_C::get_log_level(void) const
{
    return mLevel;
}

/** virtual function **/
/** set_log_level    **/
//! Sets the logging level.
/// \return void
/// \param    LYNX_E_LOG_LEVEL level
///         The new level you want to set.
void LogManager_C::set_log_level(LYNX_E_LOG_LEVEL level)
{
    mLevel = level;
}

/** virtual function   **/
/** set_event_receiver **/
//! Sets the eventreceiver to send the events to.
/// \return void
/// \param    EventReceiver *receiver
///         A pointer to the desired eventreceiver.
void LogManager_C::set_event_receiver(EventReceiver* receiver)
{
    mReceiver = receiver;
}

/** virtual function **/
/** log              **/
//! Logs something.
/// \return void
/// \param    const char* text
///         The text you want to log.
/// \param    LYNX_E_LOG_LEVEL level
///         The level of the message.
void LogManager_C::log(const char* text,
                       LYNX_E_LOG_LEVEL level)
{
    if(level < mLevel)
        return;

    if(mReceiver)
    {
        LogEvent event;
        event.mText = text;
        event.mLevel = level;
        if(mReceiver->on_event(event))
            return;
    }

    for(uint32_t a = 0; a < mOutputs.size(); a++)
        mOutputs[a]->print(text);
}

/** virtual function **/
/** log              **/
//! Logs something.
/// \return void
/// \param    const char* text
///         The text you want to log.
/// \param    const char* hint
///         The hint you want to append to the text.
/// \param    LYNX_E_LOG_LEVEL level
///         The level of the message.
void LogManager_C::log(const char* text,
                       const char* hint,
                       LYNX_E_LOG_LEVEL level)
{
    if(level < mLevel)
        return;

    std::string s = text;
    s += ": ";
    s += hint;
    log(s.c_str(), level);
}

/** virtual function **/
/** log              **/
//! Logs something.
/// \return void
/// \param    const wchar_t* text
///         The text you want to log.
/// \param    LYNX_E_LOG_LEVEL level
///         The level of the message.
void LogManager_C::log(const wchar_t* text,
                       LYNX_E_LOG_LEVEL level)
{
    if(level < mLevel)
        return;

    uint32_t l = wcslen(text);
    char* str = new char[l];
    wcstombs(str, text, l);
    std::string s = str;

    log(s.c_str(), level);
}

/** virtual function **/
/** log              **/
//! Logs something.
/// \return void
/// \param    const wchar_t* text
///         The text you want to log.
/// \param    const wchar_t* hint
///         The hint you want to append to the text.
/// \param    LYNX_E_LOG_LEVEL level
///         The level of the message.
void LogManager_C::log(const wchar_t* text,
                       const wchar_t* hint,
                       LYNX_E_LOG_LEVEL level)
{
    if(level < mLevel)
        return;

    uint32_t l1 = wcslen(text);
    char* str1 = new char[l1];
    wcstombs(str1, text, l1);
    std::string s1 = str1;

    uint32_t l2 = wcslen(hint);
    char* str2 = new char[l2];
    wcstombs(str2, hint, l2);
    std::string s2 = str2;

    log(s1.c_str(), s2.c_str(), level);
}

/** const virtual function **/
/** get_output_count       **/
//! Returns the total amount of outputs.
/// \return uint32_t
///         The total amount of outputs.
/// \param  void
uint32_t LogManager_C::get_output_count(void) const
{
    return mOutputs.size();
}

/** virtual function **/
/** remove_output    **/
//! Removes an output.
/// \return void
/// \param    uint32_t index
///         The index of the output to remove.
void LogManager_C::remove_output(uint32_t index)
{
    if(index < mOutputs.size())
    {
        LogOutput* out = mOutputs[index];
        mOutputs.erase(mOutputs.begin()+index-1);
        out->decrement_counter();
    }
}

/** virtual function **/
/** add_output      **/
//! Adds an output.
/// \return void
/// \param    LogOutput* output
///         A pointer to a logoutput to add.
void LogManager_C::add_output(LogOutput* output)
{
    output->increment_counter();
    mOutputs.push_back(output);
}

/** default constructor **/
LogOutputConsole_C::LogOutputConsole_C()
{
    //
}

/** default destructor **/
LogOutputConsole_C::~LogOutputConsole_C()
{
    //
}

/** virtual function **/
/** print            **/
//! Prints text somewhere, depends on implementation.
/// \return void
/// \param    const char *text
///         The text you want to print/display somewhere.
void LogOutputConsole_C::print(const char* text)
{
    printf("%s\n", text);
}

} // namespace Lynx
